﻿using Loli.Library.Util;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Loli.Library.Util
{

    public class KeyboardMouseOperator
    {

        public static void MouseDoubleClick()
        {
            KeyboardMouseOperator.MouseClick(true, true);
            Thread.Sleep(80);
            KeyboardMouseOperator.MouseClick(true, false);
            Thread.Sleep(80);
            KeyboardMouseOperator.MouseClick(true, true);
            Thread.Sleep(80);
            KeyboardMouseOperator.MouseClick(true, false);
        }

        public static void InputString(string str)
        {
            //输入账户名
            foreach (var item in str)
            {
                if (item == '@')
                {
                    KeyboardMouseOperator.KeyDown(Keys.LShiftKey);
                    KeyboardMouseOperator.KeyPress(Keys.D2);
                    KeyboardMouseOperator.KeyUp(Keys.LShiftKey);
                }
                else if (item == '.')
                {
                    KeyboardMouseOperator.KeyPress(Keys.Decimal);
                }
                else if (item == '1')
                {
                    KeyboardMouseOperator.KeyPress(Keys.D1);
                }
                else if (item == '2')
                {
                    KeyboardMouseOperator.KeyPress(Keys.D2);
                }
                else if (item == '3')
                {
                    KeyboardMouseOperator.KeyPress(Keys.D3);
                }
                else if (item == '4')
                {
                    KeyboardMouseOperator.KeyPress(Keys.D4);
                }
                else if (item == '5')
                {
                    KeyboardMouseOperator.KeyPress(Keys.D5);
                }
                else if (item == '6')
                {
                    KeyboardMouseOperator.KeyPress(Keys.D6);
                }
                else if (item == '7')
                {
                    KeyboardMouseOperator.KeyPress(Keys.D7);
                }
                else if (item == '8')
                {
                    KeyboardMouseOperator.KeyPress(Keys.D8);
                }
                else if (item == '9')
                {
                    KeyboardMouseOperator.KeyPress(Keys.D9);
                }
                else if (item == '0')
                {
                    KeyboardMouseOperator.KeyPress(Keys.D0);
                }
                else if (item == '+')
                {
                    KeyboardMouseOperator.KeyPress(Keys.Add);
                }
                else
                {
                    Keys key = (Keys)Enum.Parse(typeof(Keys), item.ToString().ToUpper());
                    KeyboardMouseOperator.KeyPress(key);
                }
            }
        }


        private static Point Convert(Point point)
        {
            Point returnValue = new Point();
            returnValue.X = (int)(point.X / (double)Screen.PrimaryScreen.Bounds.Width * 65335);
            returnValue.Y = (int)(point.Y / (double)Screen.PrimaryScreen.Bounds.Height * 65335);

            return returnValue;
        }


        static public void KeyDown(Keys key)
        {
            Send(key, false);
        }

        static public void KeyUp(Keys key)
        {
            Send(key, true);
        }

        static public void KeyPress(Keys key)
        {
            KeyDown(key);
            KeyUp(key);
        }

        static private void Send(Keys key, bool up)
        {
            Loli.Library.Util.WinAPI.InputUnion u = new Loli.Library.Util.WinAPI.InputUnion
             {
                 ki = new WinAPI.KEYBDINPUT
                 {
                     wVk = (ushort)key,
                     wScan = 0,
                     dwFlags = up ? WinAPI.KEYEVENTF_KEYUP : 0,
                     dwExtraInfo = WinAPI.GetMessageExtraInfo(),
                 }
             };

            Send(WinAPI.INPUT_KEYBOARD, u);
        }

        public static void MouseMove(Point p)
        {
            WinAPI.MOUSEINPUT myMinput = new WinAPI.MOUSEINPUT();

            p = Convert(p);

            myMinput.dx = p.X;
            myMinput.dy = p.Y;
            myMinput.mouseData = 0;
            myMinput.dwFlags = WinAPI.MOUSEEVENT_ABSOLUTE | WinAPI.MOUSEEVENT_MOVE;//| MouseEvent_LeftDown | MouseEvent_LeftUp;

            myMinput.time = 0;

            WinAPI.InputUnion u = new WinAPI.InputUnion
            {
                mi = myMinput
            };

            Send(WinAPI.INPUT_MOUSE, u);
        }


        public static void MouseClick(bool isLeft, bool isDown)
        {
            WinAPI.MOUSEINPUT myMinput = new WinAPI.MOUSEINPUT();

            myMinput.mouseData = 0;
            if (isLeft)
            {
                myMinput.dwFlags = isDown ? (uint)WinAPI.MOUSEEVENT_LEFTDOWN : (uint)WinAPI.MOUSEEVENT_LEFTUP;
            }
            else
            {
                myMinput.dwFlags = isDown ? (uint)WinAPI.MOUSEEVENT_RIGHTDOWN : (uint)WinAPI.MOUSEEVENT_RIGHTUP;
            }

            myMinput.time = 0;

            WinAPI.InputUnion u = new WinAPI.InputUnion
            {
                mi = myMinput
            };

            Send(WinAPI.INPUT_MOUSE, u);
        }


        public static void MouseClick(bool isLeft)
        {
            WinAPI.MOUSEINPUT myMinput = new WinAPI.MOUSEINPUT();

            myMinput.mouseData = 0;
            if (isLeft)
            {
                myMinput.dwFlags = WinAPI.MOUSEEVENT_LEFTDOWN | WinAPI.MOUSEEVENT_LEFTUP;
            }
            else
            {
                myMinput.dwFlags = WinAPI.MOUSEEVENT_RIGHTDOWN | WinAPI.MOUSEEVENT_RIGHTUP;
            }

            myMinput.time = 0;

            WinAPI.InputUnion u = new WinAPI.InputUnion
            {
                mi = myMinput
            };

            Send(WinAPI.INPUT_MOUSE, u);
        }

        private static void Send(int type, WinAPI.InputUnion intputUnion)
        {
            WinAPI.INPUT[] inputs = new WinAPI.INPUT[] {
                new WinAPI.INPUT
                {
                    type = type,
                    u = intputUnion
                }
            };

            WinAPI.SendInput((uint)inputs.Length, inputs, Marshal.SizeOf(typeof(WinAPI.INPUT)));
        }
    }
}